package tcpproxyrouter

import (
	"context"
	"fmt"
	"go-gateway-learn/dao"
	"go-gateway-learn/reverseproxy"
	tcpproxymiddleware "go-gateway-learn/tcp_proxy_middleware"
	tcpserver "go-gateway-learn/tcp_server"
	"log"
	"net"
)

var tcpServerList = []*tcpserver.TCPServer{}

type tcpHandler struct{}

func (t *tcpHandler) ServeTCP(ctx context.Context, src net.Conn){
	src.Write([]byte("tcpHandler\n"))
}

func TcpServeRun(){
	serviceList := dao.ServiceManagerHandler.GetTcpServiceList()
	for _, serviceItem := range serviceList{
		tempItem := serviceItem
		go func(serviceDetail *dao.ServiceDetail) {
			addr := fmt.Sprintf(":%d", serviceDetail.TCPRule.Port)
			rb, err := dao.LoadBalancerHandler.GetLoadBalancer(serviceDetail)
			if err != nil{
				log.Fatalf("[INFO] GetTcpLoadBalancer %v err:%v\n", addr, err)
				return
			}
			router := tcpproxymiddleware.NewTcpSliceRouter()
			router.Group("/").Use(
				tcpproxymiddleware.TcpFlowCountMiddleware(),
				tcpproxymiddleware.TcpFlowLimitMiddleware(),
				tcpproxymiddleware.TcpWhiteListMiddleware(),
				tcpproxymiddleware.TcpBlackListMiddleware(),
			)

			routerHandler := tcpproxymiddleware.NewTcpSliceRouterHandler(
				func(c *tcpproxymiddleware.TcpSliceRouterContext) tcpserver.TCPHandler{
					return reverseproxy.NewTcpLoadBalanceReverseProxy(c, rb)
				}, router)
			baseCTX := context.WithValue(context.Background(), "service", serviceDetail)
			tcpServer := &tcpserver.TCPServer{
				Addr: addr,
				Handler: routerHandler,
				BaseCTX: baseCTX,
			}
			tcpServerList = append(tcpServerList, tcpServer)
			log.Printf(" [INFO] tcp_proxy_run %v\n", addr)
			if err := tcpServer.ListenAndServe(); err != nil && err != tcpserver.ErrServerClosed{
				log.Fatalf(" [INFO] tcp_proxy_run %v err:%v\n", addr, err)
			}
		}(tempItem)
	}
}

func TCPServerStop(){
	for _, tcpServer := range tcpServerList{
		tcpServer.Close()
		log.Printf(" [INFO] tcp_proxy_stop %v stopped \n", tcpServer.Addr)
	}
}

